﻿using System.Threading;

namespace _07.Net8Thread
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello, World!");
            #region 1、线程运行
            //{
            //    // 1、创建线程
            //    Thread thread = new Thread(new ThreadStart(DoWork));
            //    // 2、运行代码
            //    thread.Start();
            //}
            #endregion

            #region 2、多线程运行
            //{
            //    // 1、创建线程
            //    Thread thread = new Thread(new ThreadStart(DoWork));
            //    // 2、运行代码
            //    thread.Start();

            //    // 1、创建线程
            //    Thread thread2 = new Thread(new ThreadStart(DoWork2));
            //    // 2、运行代码
            //    thread2.Start();
            //}
            #endregion

            #region 3、多线程- 线性参数 传参比如为 object
            //{
            //    // 1、创建线程
            //    Thread thread = new Thread(new ParameterizedThreadStart(DoWork3));
            //    // 2、运行代码
            //    thread.Start("线程三参数");

            //    // 1、创建线程
            //    Thread thread2 = new Thread(new ParameterizedThreadStart(DoWork4));
            //    // 2、运行代码
            //    thread2.Start("线程4参数");
            //}
            #endregion

            #region 4、多线程- 返回值
            //{
            //    // 1、创建ThreadResult
            //    ThreadResult threadResult = new ThreadResult();

            //    // 2、创建线程
            //    Thread thread = new Thread(threadResult.Dork5);
            //    // 3、运行代码
            //    thread.Start("线程5参数");

            //    // 4、线程等待
            //    thread.Join();

            //    Thread thread2 = new Thread(threadResult.Dork5);
            //    thread2.Start("线程5参数");
            //    thread2.Join();
            //    // 5、获取返回值
            //    Console.WriteLine($"返回结果{threadResult.i}");
            //}
            #endregion

            #region 5、多线程- 线程池 使用
            //{
            //    ThreadPool.QueueUserWorkItem(DoWork7, "7");
            //    ThreadPool.QueueUserWorkItem(DoWork8, "8");
            //    Console.WriteLine("线程池执行完毕");
            //}
            #endregion

            #region 6、多线程- 线程池 深入（不支持返回值）
            //{
            //    ThreadPool.QueueUserWorkItem(DoWork7, "7");
            //    ThreadPool.QueueUserWorkItem(DoWork8, "8");

            //    // 设置最大返回值
            //    ThreadPool.SetMaxThreads(24, 24);

            //    ThreadPool.GetMinThreads(out int a, out int b);
            //    ThreadPool.GetMaxThreads(out int c, out int d);
            //    ThreadPool.GetAvailableThreads(out int e, out int f);
            //    Console.WriteLine($"最小的线程池个数a:{a} b:{b}");
            //    Console.WriteLine($"最大的线程池个数c:{c} d:{d}");
            //    Console.WriteLine($"可用的线程池个数e:{e} f:{f}");
            //    Console.WriteLine("线程池执行完毕");
            //}
            #endregion

            #region 7、多线程-Task 运行
            //{
            //    // 1、使用Task运行代码
            //    Task task = Task.Run(() => DoWork9("运行参数"));
            //    Task<string> task92 = Task.Run(() => DoWork92("运行参数"));
            //    Console.WriteLine(task92.Result);
            //}
            #endregion

            #region 8、多线程-并行 
            //{
            //    // 1、使用Task运行代码
            //    List<Action> actions = new List<Action>();
            //    actions.Add(() => DoWork9("参数91"));
            //    actions.Add(() => DoWork9("参数92"));
            //    actions.Add(() => DoWork9("参数93"));

            //    // 2、并行运行
            //    Parallel.ForEach(actions, ts => { ts.Invoke(); });
            //    Console.WriteLine("多线程-并行");
            //}
            #endregion

            #region 9、多线程-并行 设置核数
            //{
            //    // 1、使用Task运行代码
            //    List<Action> actions = new List<Action>();
            //    actions.Add(() => DoWork9("参数91"));
            //    actions.Add(() => DoWork9("参数92"));
            //    actions.Add(() => DoWork9("参数93"));

            //    // 2、并行运行

            //    //2.1 指定运行的核数
            //    ParallelOptions parallelOptions = new ParallelOptions();
            //    parallelOptions.MaxDegreeOfParallelism = 2;

            //    Parallel.ForEach(actions, parallelOptions, ts => { ts.Invoke(); });
            //    Console.WriteLine("多线程-并行");
            //}
            #endregion

            #region 10、多线程-并发
            //{
            //    // 1、使用Task运行代码
            //    List<Task> tasks = new List<Task>();
            //    tasks.Add(Task.Run(() => DoWork9("参数91")));
            //    tasks.Add(Task.Run(() => DoWork9("参数92")));
            //    tasks.Add(Task.Run(() => DoWork9("参数93")));

            //    // 调用一个线程
            //    //List<Task> tasks = new List<Task>();
            //    tasks.Add(DoWork112("参数1"));
            //    tasks.Add(DoWork112("参数2"));
            //    tasks.Add(DoWork112("参数3"));

            //    // 2、并发运行
            //    Task.WhenAll(tasks).Wait();
            //    Console.WriteLine("多线程-并发");
            //}
            #endregion

            #region 11、多线程-线程等待
            {
                // 1、创建子线程
                Task task = Task.Run(() =>
                {
                    //1.1、开始执行
                    Console.WriteLine("子线程执行开始");
                    //1.2 执行业务逻辑花费的时间
                    Task.Delay(2000).Wait();
                    //1.3、结束执行
                    Console.WriteLine("子线程执行结束");
                });

                // 2、等待子线程执行完成
                task.Wait();
                Console.WriteLine("多线程-并发");
            }
            #endregion

            #region 12、多线程-线程中断
            {
                // 1、创建CancellationToken
                CancellationTokenSource ct = new CancellationTokenSource();
                CancellationToken cancellationToken = ct.Token;
                // 2、创建子线程
                Task task = Task.Run(() =>
                {
                    for (int i = 0; i < 10; i++)
                    {
                        Task.Delay(1000).Wait();
                        if (cancellationToken.IsCancellationRequested)
                        {
                            Console.WriteLine("子线程任务取消");
                            cancellationToken.ThrowIfCancellationRequested();
                        }
                        //1.1、开始执行
                        //1.2 执行业务逻辑花费的时间
                        //1.3、结束执行
                        Console.WriteLine($"子线程执行结束{i}");
                    }

                }, cancellationToken);
                // 3、等待
                Task.Delay(3200).Wait();
                //4、取消线程
                ct.Cancel();
                // 2、等待子线程执行完成
                try
                {
                    task.Wait();
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"{ex.Message}");
                }

                Console.WriteLine("多线程-并发");
            }
            #endregion
        }

        private static void DoWork()
        {
            Console.WriteLine("线程1开始执行");
        }

        private static void DoWork2()
        {
            Console.WriteLine("线程2开始执行");
        }

        private static void DoWork3(object par)
        {
            Console.WriteLine($"线程3开始执行{par}");
        }
        private static void DoWork4(object par)
        {
            Console.WriteLine($"线程4开始执行{par}");
        }


        private static void DoWork7(object par)
        {
            Console.WriteLine($"线程7开始执行{par}");
        }

        private static void DoWork8(object par)
        {
            Console.WriteLine($"线程8开始执行{par}");
        }

        private static void DoWork9(object par)
        {
            Console.WriteLine($"线程9开始执行{par} 线程ID:{Thread.CurrentThread.ManagedThreadId}");
        }
        private static string DoWork92(object par)
        {
            Console.WriteLine($"线程92开始执行{par}");
            return "执行成功";
        }

        private static string DoWork11(object par)
        {
            Console.WriteLine($"线程11开始执行{par} 线程ID:{Thread.CurrentThread.ManagedThreadId}");
            return "执行成功";
        }

        private static async Task DoWork112(object par)
        {
            Console.WriteLine($"线程11开始执行{par} 线程ID:{Thread.CurrentThread.ManagedThreadId}");
        }
    }
}
